home *** CD-ROM | disk | FTP | other *** search
- ; Grants Computing decrunchers
- ; by Kyzer/CSG & Kenny Grant
- ;
- ; 1.0: works OK, could probably do with range checks on relocs and validity
- ; checks on compressed data. syskiller GC!2 formats still todo
- ; 1.1: now includes data slaves, but not GC!2 exe formats
- ;
- ; Kenny Grant compiled Amiga Power coverdisks for issues 20-43 and
- ; 50-55, he also did some stuff for CU Amiga. Read the story of the AP
- ; coverdisk at http://dspace.dial.pipex.com/ap2/comments/JN/disks.html
- ;
- ; Thanks to Mr.Larmer for writing the previous datafile-only slave, called
- ; 'GraftGold', however the decrunch code I first extracted from the example
- ; files exactly matched the graftgold slave, so technically I didn't need
- ; to refer to his slave...
-
- include dos/doshunks.i
- include exec/memory.i
- include libraries/xfdmaster.i
- include lvo/exec_lib.i
-
- IFD TEST
- include xfdExeHead.a
- ENDC
-
- ForeMan dc.l $70FF4E75,XFDF_ID ; id
- dc.w XFDF_VERSION ; foreman version
- dcb.w 5,0 ; reserved stuff
- ; dc.l GC2exe ; first slave
- dc.l GC2data ; first slave
-
- dc.b '$VER: KennyGrant 1.0 (22.01.2000) by <kyzer@4u.net>',0
- GC2exe_name dc.b 'Grants Computing (GC!2)',0
- GC3exe_name dc.b 'Grants Computing (GC!3)',0
- GC2data_name dc.b 'Grants Computing (GC!2) Data',0
- GC3data_name dc.b 'Grants Computing (GC!3) Data',0
- cnop 0,4
-
- GC2exe dc.l GC2data
- dc.w 2,38
- dc.l GC2exe_name
- dc.w XFDPFF_ADDR,0
- dc.l GC2exe_recog,GC2exe_decrunch,0,0
- dc.l 0,1024 ;******** Calculate this right!!
-
- GC2data dc.l GC3exe
- dc.w 2,39 ; slave v2+ requires master v39+
- dc.l GC2data_name
- dc.w XFDPFF_DATA!XFDPFF_RECOGLEN!XFDPFF_USERTARGET,0
- dc.l GC2data_recog,GC2data_decrunch,GC2data_scan,GC2data_verify
- dc.l 0,18
-
- GC3exe dc.l GC3data
- dc.w 2,38
- dc.l GC3exe_name
- dc.w XFDPFF_RELOC,0
- dc.l GC3exe_recog,GC3exe_decrunch,0,0
- dc.l 0,44+944
-
- GC3data dc.l 0
- dc.w 2,39
- dc.l GC3data_name
- dc.w XFDPFF_DATA!XFDPFF_RECOGLEN!XFDPFF_USERTARGET,0
- dc.l GC3data_recog,GC3data_decrunch,GC3data_scan,GC3data_verify
- dc.l 0,18
-
-
- ;****************************************************************************
- ;****************************************************************************
- ;****************************************************************************
- ;
- ; GC!2 and GC!3 crunched data format:
- ; longword ID: GC!\02 or GC!\03
- ; longword unpacked length
- ; longword packed length
- ; remainder is crunched stuff (6 bytes immediately & unconditionally read)
- ; total for minimum: 18 bytes
-
-
- GC2_ID = ("G"<<24) + ("C"<<16) + ("!"<<8) + 2
- GC3_ID = ("G"<<24) + ("C"<<16) + ("!"<<8) + 3
-
- GC2data_recog
- move.l #GC2_ID,d0
- bra.s __recog
- GC3data_recog
- move.l #GC3_ID,d0
- __recog cmp.l (a0)+,d0
- bne.s .fail
- move.l (a0)+,d0 ; d0 = unpacked length
- beq.s .fail ; fail if unpacked length = 0
- move.l (a0)+,d1 ; d1 = packed length
- beq.s .fail ; fail if packed length = 0
- cmp.l d0,d1
- bhi.s .fail ; fail if packed length > unpacked
- move.l d0,xfdrr_FinalTargetLen(a1)
- add.l #52,d0 ; safety for GC!2 (see GC2_DECRUNCH)
- move.l d0,xfdrr_MinTargetLen(a1)
- moveq #12,d0
- add.l d0,d1
- move.l d1,xfdrr_MinSourceLen(a1)
- moveq #1,d0 ; return success
- rts
- .fail moveq #0,d0
- rts
-
- GC2data_decrunch
- move.l a2,-(sp)
- lea GC2_DECRUNCH(pc),a2
- bra.s __decr
- GC3data_decrunch
- move.l a2,-(sp)
- lea GC3_DECRUNCH(pc),a2
- __decr move.l xfdbi_UserTargetBuf(a0),a1
- move.l xfdbi_SourceBuffer(a0),a0
- addq.l #4,a0
- jsr (a2)
- move.l (sp)+,a2
- rts
-
- GC2data_scan
- moveq #0,d0
- cmp.l #GC2_ID,(a0)
- bne.s .fail
- moveq #1,d0
- .fail rts
- GC3data_scan
- moveq #0,d0
- cmp.l #GC3_ID,(a0)
- bne.s .fail
- moveq #1,d0
- .fail rts
-
-
- GC2data_verify
- GC3data_verify
- moveq #12,d1
- add.l 8(a0),d1 ; d1 = packed length
- cmp.l d0,d1
- bhi.s .fail ; fail if packed len > remaining len
- cmp.l 4(a0),d1
- bhi.s .fail ; fail if packed len > unpacked len
- move.l d1,d0
- rts
- .fail moveq #0,d0
- rts
-
-
-
-
- ;****************************************************************************
- ;****************************************************************************
- ;****************************************************************************
- ;
- ;Grants Computing (Kenny Grant) GC!2 syskiller format
-
-
- GC2exe_recog
- moveq #0,d0
- rts
-
- GC2exe_decrunch
- moveq #0,d0
- rts
-
-
- ;Grants Computing (Kenny Grant) GC!3 overlay format
- ;
- ;Executable overlay header (a few changes to the code here and there),
- ;performs a SEEK call with an offset - matches with the first byte after
- ;the hunk_overlay header the real data starts there.
- ;
- ;(1) a longword listing the total number of hunks.
- ;
- ;(2) one longword for each hunk representing arguments to AllocMem():
- ; - (upper 8 bits >>24)|MEMF_CLEAR -> lower 8 bits of D1
- ; - lower 24 bits && $00FFFFFF -> D0
- ;
- ;(3) here begins a loop for each hunk in the decrunched file
- ; - one longword that states what the hunk is:
- ; 944 & 932 BYTES VERSION
- ; - longword < 0: throw away next longword, goto (3) ; 944 only?
- ; - longword = 0: copy verbatim to fill the hunk, goto (4)
- ; 924 & 936 BYTES VERSION
- ; - longword = 0: goto (3)
- ; ALL VERSIONS
- ; - longword > 0: (always "GC!"<<8+3) if size!=0 decruncher; goto (4)
- ;
- ;(4) if longword >=0 (ie isn't BSS), there may be relocs
- ; - standard reloc format (num, hunk, relocs[num], num...)
- ; - if first num=0, there are no relocs
- ;
- ;Examples:
- ;944 byte ver: AP38a:AtomSmasher, AP39a:TrickorTreat, AP38a:VectorBattleGround
- ;936 byte ver: AP34a:SmidgeDemo, AP38a:SuperObliteration
- ;932 byte ver: AP37a:Monaco
- ;924 byte ver: AP35:Statix
-
- GC3exe_recog
- cmp.l #HUNK_HEADER,(a0) ; executable?
- bne.s .fail
- cmp.w #2,10(a0) ; 2 hunks?
- bne.s .fail
- lea 32(a0),a0
- move.l (a0)+,d0 ; a0 = start of code hunk
- asl.l #2,d0 ; d0 = size of code hunk
- cmp.l #944,d0
- bhi.s .fail ; code size <= 944 bytes?
- lea (a0,d0.w),a1 ; a1 = end of code hunk
- cmp.l #HUNK_OVERLAY,4(a1) ; hunk 2 = overlay?
- bne.s .fail
-
- cmp.w #$6000,(a0) ; check bra.w instruction
- bne.s .fail
- addq.l #2,a0
- adda.w (a0),a0 ; skip past overlay header
-
- ; check the code itself
- cmp.l #$4eadffc4,$18(a0) ; check jsr _LVOOutput(a5)
- bne.s .fail
- cmp.b #$67,$1E(a0) ; check for 944 byte version
- bne.s .not944 ; which has an extra instruction here
- addq.l #2,a0 ; compensate for extra instruction
- .not944 cmp.w #$243A,$30(a0) ; check for 936 byte version
- bne.s .not936 ; which has 'move.l xxx(pc),d2'
- move.w $32(a0),d1 ; d1 = xxxx
- lea $32(a0,d1.w),a1 ; a1 = xxxx(pc)
- move.l (a1),d1 ; d1 = offset
- bra.s .cont
- .not936 cmp.w #$243C,$30(a0) ; check for other versions
- bne.s .fail ; which have 'move.l #offset,d2'
- move.l $32(a0),d1 ; d1 = offset
- .cont add.l #52,d0 ; check offset == (codesize+52)
- cmp.l d0,d1
- bne.s .fail
-
- moveq #1,d0
- rts
- .fail moveq #0,d0
- rts
-
-
- STRUCTURE myhunk,0
- ULONG h_len
- APTR h_addr
- UBYTE h_pad
- UBYTE h_memflags
- UBYTE h_isbss
- UBYTE h_ispacked
- LABEL h_SIZEOF
-
- MAX_HUNKS=20 ; this is an arbitrary number
- hunks=-h_SIZEOF*MAX_HUNKS
-
- GC3exe_decrunch
- movem.l d2-d7/a2-a6,-(sp)
- link a5,#hunks ; a5 = hunks
- move.l a0,a4 ; a4 = BufferInfo
-
- move.w #XFDERR_CORRUPTEDDATA,xfdbi_Error(a4)
- move.l xfdbi_SourceBuffer(a4),a3
- move.l a3,a0
- lea 36(a3),a2 ; a2 = start of code (temp)
- bsr GC3exe_recog ; d1 = offset of data
- lea (a3,d1.w),a3 ; a3 = start of data
-
-
- ; A0=data_ptr A4=BufferInfo A5=hunks A6=current_hunk
- ; D4=relocs_size D5=944style D6=current_hunk D7=number_hunks
- ; A1/A2/A3/D0/D1/D2/D3/D4=scratch
-
-
- ; check which version of code this file is
- ; ('944 style' means code=0 for unpacked)
- ; ('not 944 style' means code=0 for bss)
- move.b $fa(a2),d0
-
- moveq #1,d5
- cmp.b #$6a,d0 ; 944 byte version (944style)
- beq.s .styled
- cmp.b #$22,d0 ; 932 byte version (944style)
- beq.s .styled
-
- moveq #0,d5
- cmp.b #$53,d0 ; 936 byte version (not 944style)
- beq.s .styled
- cmp.b #$20,d0 ; 924 byte version (not 944style)
- bne .fail
- .styled
-
-
- ; get the number of hunks
- move.l a3,a0 ; a0 = data_ptr
- move.l (a0)+,d7 ; d7 = number of hunks
- cmp.l #MAX_HUNKS,d7
- bhi .fail ; fail if too many hunks for us
-
-
- ; get the sizes/flags of hunks
- lea hunks(a5),a6 ; FOR all hunks
- move.l d7,d6
-
- 01$ move.l (a0)+,d0 ; read len/memflags
- move.l d0,d1
- andi.l #$ffffff,d0 ; extract length of hunk
- move.l d0,h_len(a6) ; and store it
- andi.w #3,d0
- bne .fail ; hunksize must be multiple of 4
- rol.l #8,d1 ; extract memflags of hunk
- clr.l h_pad(a6) ; clear isbss/ispacked/memflags
- move.b d1,h_memflags(a6) ; store memflags
-
- lea h_SIZEOF(a6),a6 ; NEXT
- subq #1,d6
- bne.s 01$
-
-
- ; get types and relocs of hunks
- moveq #0,d4 ; d4 = size of relocs
- lea hunks(a5),a6 ; FOR all hunks
- move.l d7,d6
-
- 11$ move.l (a0)+,d0 ; read typeid
- bne.s .nzero ; typeid=0 is ambiguous
- tst.l d5
- bne.s .israw ; typeid=0 944style is raw data
- .isbss st.b h_isbss(a6) ; typeid=0 !944style is bss
- bra.s 12$
- .nzero bpl.s .ispack ; typeid>0 is always packed data
- tst.l d5
- beq .fail ; typeid<0 944style is bss
- addq.l #4,a0 ; 944style bss has extra long (why?)
- bra.s .isbss
-
- .israw move.l a0,h_addr(a6) ; remember where data is
- add.l h_len(a6),a0 ; skip to end of data
- bra.s .relocs ; raw data can have relocs
-
- .ispack move.l a0,h_addr(a6) ; remember where data is
- st.b h_ispacked(a6)
- tst.l h_len(a6)
- beq.s .relocs ; no data if hunk is empty
- addq.l #4,a0 ; skip unpacked size
- add.l (a0)+,a0 ; skip to end of packed data
- ; bra.s .relocs ; packed data can have relocs
-
- .relocs move.l a0,d1 ; d1 = start of relocs
- move.l (a0)+,d0 ; get number of relocs
- beq.s 12$ ; finish if relocs=0
- addq.l #4,d4 ; add hunk_reloc id to reloc size
- 13$ asl.l #2,d0
- lea 4(a0,d0.w),a0 ; skip to more relocs or end
- move.l (a0)+,d0 ; if there are more relocs, go back
- bne.s 13$
- move.l a0,d0
- sub.l d1,d0 ; d0 = size of relocs (end-start)
- add.l d0,d4 ; add to reloc size
-
- 12$ lea h_SIZEOF(a6),a6 ; NEXT hunk
- subq #1,d6
- bne.s 11$
-
- ; calculate size of output executable
- ; = (4*5) hunk_header,0,n,0,n-1
- ; + 4*4*numhunks sizeinhdr,hunkid,hunksize,hunk_end
- ; + relocs
-
- moveq #4*5,d0 ; 4*5
- move.l d7,d1
- asl.l #4,d1
- add.l d1,d0 ; + 4*4*number_of_hunks
- add.l d4,d0 ; + size of relocs
-
- ; sum non-BSS hunk sizes
- lea hunks(a5),a6 ; FOR all hunks
- move.l d7,d6
- 21$ tst.b h_isbss(a6) ; if hunk isn't bss
- bne.s .izbss
- add.l h_len(a6),d0 ; add its value to the total
- .izbss lea h_SIZEOF(a6),a6 ; NEXT
- subq #1,d6
- bne.s 21$
-
- ; d0 = calculated size
-
- ; allocate memory
- move.w #XFDERR_NOMEMORY,xfdbi_Error(a4)
- move.l d0,xfdbi_TargetBufLen(a4)
- move.l d0,xfdbi_TargetBufSaveLen(a4)
- move.l xfdbi_TargetBufMemType(a4),d1
- move.l 4.w,a6
- jsr _LVOAllocMem(a6)
- move.l d0,xfdbi_TargetBuffer(a4)
- beq .fail
- move.l d0,a1 ; a1 = output
-
-
- ; A0/A3/A4/A6=scratch A1=output A5=hunks A6=current_hunk
- ; D0/D1/D2/D3/D4/D5=scratch D6=current_hunk D7=number_hunks
-
- ; write hunk header
- move.l #HUNK_HEADER,(a1)+ ; write header
- clr.l (a1)+ ; write name (null)
- move.l d7,d0
- move.l d0,(a1)+ ; write num_hunks
- clr.l (a1)+ ; write first hunk (0)
- subq #1,d0
- move.l d0,(a1)+ ; write last hunk (num_hunks-1)
- lea hunks(a5),a6
- 31$ move.l h_len(a6),d1 ; get length
- asr.l #2,d1 ; bytes->longwords
-
- btst.b #MEMB_CHIP,h_memflags(a6)
- beq.s .nochip
- bset #30,d1 ; set 'chip mem' flag if needed
- bra.s .nofast
- .nochip btst.b #MEMB_FAST,h_memflags(a6)
- beq.s .nofast
- bset #31,d1 ; set 'fast mem' flag if needed
- .nofast
- move.l d1,(a1)+ ; write hunk length
- lea h_SIZEOF(a6),a6
- dbra d0,31$
-
-
- ; write hunks
- move.l d7,d6 ; FOR all hunks
- lea hunks(a5),a6
-
- 32$ move.l h_len(a6),d0 ; get length
- asr.l #2,d0 ; bytes->longwords
- tst.b h_isbss(a6)
- beq.s .nobss
- move.l #HUNK_BSS,(a1)+ ; BSS hunk is just header
- move.l d0,(a1)+ ; and length
- bra.s .h_end
-
- .nobss move.l #HUNK_CODE,(a1)+ ; data hunks are header
- move.l d0,(a1)+ ; length, and contents
-
- move.l h_addr(a6),a0 ; get address of data
- tst.b h_ispacked(a6)
- beq.s .raw
- tst.l h_len(a6) ; skip onwards if no data
- beq.s .reloc
- bsr.s GC3_DECRUNCH ; otherwise decrunch from a0 to a1
- addq.l #4,a0 ; skip past crunched data
- add.l (a0)+,a0 ; so a0 points at relocs
- add.l h_len(a6),a1 ; advance output ptr
- bra.s .reloc
-
- .raw move.l (a0)+,(a1)+ ; raw is just copy
- subq.l #1,d0 ; use length as num of longs to copy
- bne.s .raw ; a0 is left pointing at relocs
-
- ; write relocs if need be
- .reloc move.l (a0)+,d0 ; get number of relocs
- beq.s .h_end ; finish hunk if none
- move.l #HUNK_RELOC32,(a1)+ ; otherwise write reloc id
- 33$ move.l d0,(a1)+ ; write number of relocs
- move.l (a0)+,(a1)+ ; write reloc hunk
- 34$ move.l (a0)+,(a1)+
- subq #1,d0 ; LOOP for number of relocs
- bne.s 34$
- move.l (a0)+,d0 ; if there are more relocs
- bne.s 33$ ; go do them
- move.l #0,(a1)+ ; terminate reloc list
-
- .h_end move.l #HUNK_END,(a1)+ ; write hunk_end id
- lea h_SIZEOF(a6),a6 ; NEXT hunk
- subq #1,d6
- bne.s 32$
-
- ; success
- clr.w xfdbi_Error(a4)
- moveq #1,d0
- bra.s .done
- .fail moveq #0,d0
- .done unlk a5
- movem.l (sp)+,d2-d7/a2-a6
- rts
-
-
- ;****************************************************************************
- ;****************************************************************************
- ;****************************************************************************
- ;
- ; GC!3 decruncher: A0=source (after header), A1=dest
-
- GC3_DECRUNCH
- movem.l d0-d7/a0-a6,-(sp)
- lea -$620(sp),sp
- move.l (a0)+,d1 ; d1 = unpacked length
- lea 0(a1,d1.l),a1 ; a1 = end of destination buffer
- move.l (a0)+,d2 ; d2 = packed length
-
- ; move.l a0,d0 ; this bit of code arranges that
- ; add.l d2,d0 ; the 5kb read buffer which is
- ; sub.l DATA_BUFFER(pc),d0 ; indexed by a0 is left pointing
- ; divu.w #5120,d0 ; at the right address after this
- ; clr.w d0 ; routine finishes - of course,
- ; swap d0 ; there's no 5kb buffer in the
- ; add.l DATA_BUFFER(pc),d0 ; the slave, so just take it
- ; move.l d0,$640(sp) ; out
-
- lea $20(sp),a6
- move.w (a0)+,d0
- move.l (a0)+,d6
- moveq #$10,d7
- sub.w d0,d7
- lsr.l d7,d6
- move.w d0,d7
- moveq #$10,d3
- 1$ lea (sp),a2
- bsr.l 12$
- moveq #$10,d1
- bsr.l 10$
- move.w d0,d5
- lea $9E(a6),a2
- lea -$1E(a2),a5
- 2$ movea.l a6,a4
- bsr.s 6$
- btst #8,d0
- bne.s 5$
- move.w d0,d4
- lea $20(a6),a4
- exg a5,a2
- bsr.s 6$
- exg a5,a2
- move.w d0,d1
- move.w d0,d2
- bne.s 3$
- moveq #1,d1
- moveq #$10,d2
- 3$ bsr.l 10$
- bset d2,d0
- lea 1(a1,d0.w),a3
- 4$ move.b -(a3),-(a1)
- subq.w #1,d4
- bpl.s 4$
- move.b -(a3),-(a1)
- move.b -(a3),d0
- 5$ move.b d0,-(a1)
- subq.w #1,d5
- bpl.s 2$
- moveq #1,d1
- bsr.s 10$
- bne.s 1$
- lea $620(sp),sp
- movem.l (sp)+,d0-d7/a0-a6
- rts
-
- 6$ moveq #0,d1
- 7$ subq.w #1,d7
- beq.s 8$
- lsr.l #1,d6
- bra.s 9$
-
- 8$ moveq #$10,d7
- move.w d6,d0
- lsr.l #1,d6
- swap d6
- move.w (a0)+,d6
- swap d6
- lsr.w #1,d0
- 9$ addx.w d1,d1
- move.w (a4)+,d0
- cmp.w d1,d0
- bls.s 7$
- add.w $3E(a4),d1
- add.w d1,d1
- move.w 0(a2,d1.w),d0
- rts
-
- 10$ move.w d6,d0
- lsr.l d1,d6
- sub.w d1,d7
- bgt.s 11$
- add.w d3,d7
- ror.l d7,d6
- move.w (a0)+,d6
- rol.l d7,d6
- 11$ move.l d2,-(sp)
- moveq #1,d2
- lsl.l d1,d2
- subq.l #1,d2
- move.l d2,d1
- move.l (sp)+,d2
- and.w d1,d0
- rts
-
- 12$ moveq #9,d2
- lea $9E(a6),a4
- lea -2(a6),a5
- bsr.s 13$
- moveq #4,d2
- lea $80(a6),a4
- lea $1E(a6),a5
- 13$ movem.l d2-d5/a1/a2,-(sp)
- moveq #4,d1
- bsr.s 10$
- moveq #15,d5
- sub.w d0,d5
- movea.w d5,a1
- suba.l a3,a3
- moveq #0,d4
- move.w d0,d5
- 14$ addq.w #1,d4
- move.w d4,d1
- cmp.w d2,d1
- ble.s 15$
- move.w d2,d1
- 15$ bsr.s 10$
- move.w d0,(a2)+
- adda.w d0,a3
- subq.w #1,d5
- bne.s 14$
- move.w a1,d5
- 16$ beq.s 17$
- clr.w (a2)+
- subq.w #1,d5
- bra.s 16$
-
- 17$ move.w a3,d5
- 18$ move.w d2,d1
- bsr.s 10$
- move.w d0,(a4)+
- subq.w #1,d5
- bne.s 18$
- movem.l (sp)+,d2-d5/a1/a2
- movem.l d2-d7/a2,-(sp)
- clr.w (a5)+
- moveq #0,d2
- moveq #0,d3
- moveq #-1,d4
- moveq #15,d7
- 19$ move.w (a2)+,d6
- move.w d3,$40(a5)
- move.w -2(a5),d0
- add.w d0,d0
- sub.w d0,$40(a5)
- add.w d6,d3
- add.w d6,d2
- move.w d2,(a5)+
- lsl.w #1,d2
- subq.l #1,d7
- bne.s 19$
- movem.l (sp)+,d2-d7/a2
- rts
-
-
-
- ;****************************************************************************
- ;****************************************************************************
- ;****************************************************************************
- ;
- ; GC!2 decruncher: A0=source (after header), A1=dest
-
- GC2_DECRUNCH
- movem.l d0-d7/a0-a6,-(sp)
- lea -$454(sp),sp
- ; cmpi.l #$47432102,(a0)+
- ; bne.l 9$
-
- move.l (a0)+,d1 ; d1 = unpacked length
- lea 0(a1,d1.l),a1 ; a1 = end of destination buffer
-
- ; heres a funny bit of code, that
- ; seems to 'save' the 52 bytes after
- ; the end of the decrunch buffer -
- ; does it overwrite it in the routine?
- moveq #52,d0
- lea 0(sp,d0.w),a2
- 1$ move.b (a1)+,-(a2)
- subq.l #1,d0
- bne.s 1$
-
- move.l (a0)+,d2 ; d2 = packed length
- adda.l d2,a0 ; a0 = end of source buffer
- lea $54(sp),a6
- move.w -(a0),d0
- move.l -(a0),d6
- moveq #$10,d7
- sub.w d0,d7
- lsr.l d7,d6
- move.w d0,d7
- moveq #$10,d3
- 2$ lea $34(sp),a2
- bsr.l 16$
- moveq #$10,d1
- bsr.l 14$
- move.w d0,d5
- lea $9E(a6),a2
- lea -$1E(a2),a5
- 3$
-
- ; move.l a6,-(sp)
- ; lea COLOUR1_DATA(pc),a6 ; write colour into copperlist
- ; move.w d6,(a6) ; to show decrunching
- ; movea.l (sp)+,a6
-
- movea.l a6,a4
- bsr.s 10$
- btst #8,d0
- bne.s 6$
- move.w d0,d4
- lea $20(a6),a4
- exg a5,a2
- bsr.s 10$
- exg a5,a2
- move.w d0,d1
- move.w d0,d2
- bne.s 4$
- moveq #1,d1
- moveq #$10,d2
- 4$ bsr.s 14$
- bset d2,d0
- lea 1(a1,d0.w),a3
- 5$ move.b -(a3),-(a1)
- subq.w #1,d4
- bpl.s 5$
- move.b -(a3),-(a1)
- move.b -(a3),d0
- 6$ move.b d0,-(a1)
- subq.w #1,d5
- bpl.s 3$
- moveq #1,d1
- bsr.s 14$
- bne.s 2$
- move.l -(a0),d0
- divu.w #$34,d0
- addq.w #1,d0
- 7$ movem.l (a1),d1-d7/a0/a2-a6
- movem.l d1-d7/a0/a2-a6,-(a1)
- lea $68(a1),a1
- subq.w #1,d0
- bne.s 7$
-
- ; and here it is again to restore?
- swap d0
- moveq #52,d1
- suba.l d1,a1
- adda.l d0,a1
- lea (sp),a0
- 8$ move.b (a0)+,-(a1)
- subq.l #1,d1
- bne.s 8$
-
- 9$ lea $454(sp),sp
- movem.l (sp)+,d0-d7/a0-a6
- rts
-
- 10$ moveq #0,d1
- 11$ subq.w #1,d7
- beq.s 12$
- lsr.l #1,d6
- bra.s 13$
-
- 12$ moveq #$10,d7
- move.w d6,d0
- lsr.l #1,d6
- swap d6
- move.w -(a0),d6
- swap d6
- lsr.w #1,d0
- 13$ addx.w d1,d1
- move.w (a4)+,d0
- cmp.w d1,d0
- bls.s 11$
- add.w $3E(a4),d1
- add.w d1,d1
- move.w 0(a2,d1.w),d0
- rts
-
- 14$ move.w d6,d0
- lsr.l d1,d6
- sub.w d1,d7
- bgt.s 15$
- add.w d3,d7
- ror.l d7,d6
- move.w -(a0),d6
- rol.l d7,d6
- 15$ move.l d2,-(sp)
- moveq #1,d2
- lsl.l d1,d2
- subq.l #1,d2
- move.l d2,d1
- move.l (sp)+,d2
- and.w d1,d0
- rts
-
- 16$ moveq #9,d2
- lea $9E(a6),a4
- lea -2(a6),a5
- bsr.s 17$
- moveq #4,d2
- lea $80(a6),a4
- lea $1E(a6),a5
- 17$ movem.l d2-d5/a1/a2,-(sp)
- moveq #4,d1
- bsr.s 14$
- moveq #15,d5
- sub.w d0,d5
- movea.w d5,a1
- suba.l a3,a3
- moveq #0,d4
- move.w d0,d5
- 18$ addq.w #1,d4
- move.w d4,d1
- cmp.w d2,d1
- ble.s 19$
- move.w d2,d1
- 19$ bsr.s 14$
- move.w d0,(a2)+
- adda.w d0,a3
- subq.w #1,d5
- bne.s 18$
- move.w a1,d5
- 20$ beq.s 21$
- clr.w (a2)+
- subq.w #1,d5
- bra.s 20$
-
- 21$ move.w a3,d5
- 22$ move.w d2,d1
- bsr.s 14$
- move.w d0,(a4)+
- subq.w #1,d5
- bne.s 22$
- movem.l (sp)+,d2-d5/a1/a2
- movem.l d2-d7/a2,-(sp)
- clr.w (a5)+
- moveq #0,d2
- moveq #0,d3
- moveq #-1,d4
- moveq #15,d7
- 23$ move.w (a2)+,d6
- move.w d3,$40(a5)
- move.w -2(a5),d0
- add.w d0,d0
- sub.w d0,$40(a5)
- add.w d6,d3
- add.w d6,d2
- move.w d2,(a5)+
- lsl.w #1,d2
- subq.l #1,d7
- bne.s 23$
- movem.l (sp)+,d2-d7/a2
- rts
-